package org.haredot.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.haredot.dto.DepartDTO;
import org.haredot.entity.Depart;
import org.haredot.entity.User;
import org.haredot.mapper.DepartMapper;
import org.haredot.service.DepartService;
import org.haredot.vo.DepartVo;
import org.haredot.vo.PageVo;
import org.haredot.vo.ResultVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

@Service
@Transactional(rollbackFor = Exception.class)
public class DepartServiceImpl implements DepartService {

    @Resource
    private DepartMapper departMapper ;

    @Override
    public ResultVo<Depart> saveDepart(DepartVo departVo) {
        // 部门名 和 编号 不允许重复
        Depart depart = departMapper.findDepartByName(departVo.getName()) ;

        if (depart !=null) {
            return ResultVo.<Depart>fail("部门名已存在").build();
        }

        depart = departMapper.findDepartByCode(departVo.getCode()) ;

        if (depart != null) {
            return ResultVo.<Depart>fail("部门编号已被占用").build();
        }

        // 将 部门信息 写入到 表中
        int len = departMapper.saveDepart(departVo);

        return ResultVo.<Depart>asserts(len == 1, "数据保存失败").build();
    }

    @Override
    public ResultVo<PageVo<DepartDTO>> queryDeparts(PageVo<DepartDTO> objectPageVo) {

        // 递归的查询所有的部门
        PageInfo<DepartDTO> pageInfo = PageHelper.startPage(objectPageVo).doSelectPageInfo( ()-> queryDeparts());

        /*
        // 使用 SQL 递归查询所有的部门
        PageInfo<DepartDTO> pageInfo = PageHelper.startPage(objectPageVo)
                        .doSelectPageInfo(()-> departMapper.findRecursiveDeparts());

        // 获取查询的所有数据
        List<DepartDTO> list = pageInfo.getList();
        // 组装子元素
        List<DepartDTO> result = list.stream()
                .reduce(new ArrayList<>(), (array, depart)-> {
                    if (depart.getPid() == null) {
                        array.add(depart) ;
                    } else{
                        Optional<DepartDTO> first = array.stream().filter(s -> Objects.equals(s.getId(), depart.getPid())).findFirst();

                        if (first.isPresent()) {
                            if(first.get().getChildren() == null) {
                                first.get().setChildren(new ArrayList<>(List.of(depart)));
                            }else{
                                first.get().getChildren().add(depart);
                            }
                        }else {
                            array.add(depart);
                        }
                    }
                    return array ;
                }, (a, b)-> a);
        */
        objectPageVo.setList(pageInfo.getList()).setTotal(pageInfo.getTotal()) ;

        return ResultVo.<PageVo<DepartDTO>>ok().data(objectPageVo).build();
    }

    private List<DepartDTO> queryDeparts() {
        // 负责查询数据库中  可用的所有 一级部门
        List<DepartDTO> departs = departMapper.findOneLevelDeparts() ;

        for(DepartDTO departDTO : departs) {
            List<DepartDTO> children = findDepartsByPid(departDTO.getId());
            departDTO.setChildren(children);
        }
        return departs ;
    }

    private List<DepartDTO> findDepartsByPid(Long pid) {

        List<DepartDTO> departs = departMapper.findDepartByPid(pid);

        for(DepartDTO departDTO : departs) {
            List<DepartDTO> children = findDepartsByPid(departDTO.getId());
            departDTO.setChildren(children);
        }
        return departs ;
    }

    @Override
    public ResultVo<?> modifyDepart(Depart departVo) {


        // 部门名 和 编号 不允许重复
        Depart depart = departMapper.findDepartByName(departVo.getName()) ;

        if (depart !=null && !Objects.equals(depart.getId(), departVo.getId())) {
            return ResultVo.<Depart>fail("部门名已存在").build();
        }

        depart = departMapper.findDepartByCode(departVo.getCode()) ;

        if (depart != null && !Objects.equals(depart.getId(), departVo.getId())) {
            return ResultVo.<Depart>fail("部门编号已被占用").build();
        }

        // 根据部门ID 查询对应的编号
        depart = departMapper.findDepartById(departVo.getId()) ;

        // 判断 部门的 编号 是否 发生改变
        if (depart !=null && !Objects.equals(depart.getCode(), departVo.getCode())) {
            // 如果 部门 编号 发生改变 ， 查询 该部门 下是否有 子部门，如果有 子部门，则不允许 修改
            List<DepartDTO> departByPid = departMapper.findDepartByPid(depart.getId());
            if (!departByPid.isEmpty()) {
                // 提示 错误信息
                return ResultVo.fail("该部门下有子部门、不允许修改部门编号").build();
            }
        }
        // 修改编码
        departMapper.modifyDepartById(departVo);

        return ResultVo.ok().build();
    }

    @Override
    public ResultVo<?> removeDepart(Long departId) {
        // 查询 该部门下是否有 子部门，入股有，不允许移除
        List<DepartDTO> departByPid = departMapper.findDepartByPid(departId);

        if (!departByPid.isEmpty()) {
            return ResultVo.fail("该部门存在子部门、不允许直接删除").build();
        }

        // 删除部门
        int len = departMapper.deleteById(departId);

        return ResultVo.asserts(len == 1, "数据移除失败").build();
    }

    @Override
    public ResultVo<?> queryUsers(Long departId, PageVo<User> pageVo) {

        // 查询该部门及其子部门所有的人员
        PageInfo<User> info = PageHelper.startPage(pageVo).doSelectPageInfo(() -> departMapper.findUsersByDepartId(departId));

        pageVo.setTotal(info.getTotal()).setList(info.getList());

        return ResultVo.ok().data(pageVo).build();
    }
}
